Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include <boost/asio/ip/host_name.hpp>
6 : #include <boost/functional/hash.hpp>
7 : #include <fstream>
8 : #include <iostream>
9 :
10 : #include "base/contrail_ports.h"
11 : #include "base/logging.h"
12 : #include "base/misc_utils.h"
13 : #include "base/util.h"
14 : #include <base/options_util.h>
15 : #include <base/address_util.h>
16 : #include "cmn/buildinfo.h"
17 : #include "cmn/dns_options.h"
18 : #include "config_client_manager.h"
19 :
20 : using namespace std;
21 : using namespace boost::asio::ip;
22 : namespace opt = boost::program_options;
23 : using namespace options::util;
24 :
25 : // Process command line options for dns.
26 9 : Options::Options() {
27 9 : }
28 :
29 9 : bool Options::Parse(EventManager &evm, int argc, char *argv[]) {
30 18 : opt::options_description cmdline_options("Allowed options");
31 9 : Initialize(evm, cmdline_options);
32 :
33 9 : Process(argc, argv, cmdline_options);
34 9 : return true;
35 9 : }
36 :
37 : // Initialize dns's command line option tags with appropriate default
38 : // values. Options can from a config file as well. By default, we read
39 : // options from /etc/contrail/contrail-dns.conf
40 9 : void Options::Initialize(EventManager &evm,
41 : opt::options_description &cmdline_options) {
42 9 : boost::system::error_code error;
43 9 : string hostname = host_name(error);
44 9 : string host_ip = GetHostIp(evm.io_service(), hostname);
45 9 : if (host_ip.empty()) {
46 : cout << "Error! Cannot resolve host " << hostname <<
47 0 : " to a valid IP address";
48 0 : exit(-1);
49 : }
50 :
51 18 : opt::options_description generic("Generic options");
52 :
53 : // Command line only options.
54 9 : generic.add_options()
55 18 : ("conf_file", opt::value<string>()->default_value(
56 : "/etc/contrail/contrail-dns.conf"),
57 : "Configuration file")
58 9 : ("help", "help message")
59 9 : ("version", "Display version information")
60 : ;
61 :
62 9 : uint16_t default_dns_server_port = ContrailPorts::DnsServerPort();
63 9 : uint16_t default_http_server_port = ContrailPorts::HttpPortDns();
64 :
65 9 : default_collector_server_list_.push_back("127.0.0.1:8086");
66 :
67 9 : vector<string> default_config_db_server_list;
68 9 : string default_config_db_server(host_ip + ":9042");
69 9 : default_config_db_server_list.push_back(default_config_db_server);
70 :
71 9 : vector<string> default_rabbitmq_server_list;
72 9 : string default_rabbitmq_server(host_ip + ":5672");
73 9 : default_rabbitmq_server_list.push_back(default_rabbitmq_server);
74 :
75 : // Command line and config file options.
76 18 : opt::options_description config("Configuration options");
77 9 : config.add_options()
78 18 : ("DEFAULT.collectors",
79 27 : opt::value<vector<string> >()->default_value(
80 9 : default_collector_server_list_, "127.0.0.1:8086"),
81 : "Collector server list")
82 18 : ("DEFAULT.dns_config_file",
83 18 : opt::value<string>()->default_value("dns_config.xml"),
84 : "DNS Configuration file")
85 :
86 18 : ("DEFAULT.named_config_file",
87 18 : opt::value<string>()->default_value("contrail-named.conf"),
88 : "Named Configuration file")
89 18 : ("DEFAULT.named_config_directory",
90 18 : opt::value<string>()->default_value("/etc/contrail/dns"),
91 : "Named Configuration directory")
92 18 : ("DEFAULT.named_log_file",
93 18 : opt::value<string>()->default_value("/var/log/contrail/contrail-named.log"),
94 : "Named log file")
95 18 : ("DEFAULT.rndc_config_file",
96 18 : opt::value<string>()->default_value("contrail-rndc.conf"),
97 : "Rndc Configuration file")
98 18 : ("DEFAULT.rndc_secret",
99 18 : opt::value<string>()->default_value("xvysmOR8lnUQRBcunkC6vg=="),
100 : "RNDC secret")
101 18 : ("DEFAULT.named_max_cache_size",
102 18 : opt::value<string>()->default_value("32M"),
103 : "Maximum cache size, in bytes, used by contrail-named (per view)")
104 18 : ("DEFAULT.named_max_retransmissions",
105 9 : opt::value<uint16_t>()->default_value(12),
106 : "Maximum number of retries to named")
107 18 : ("DEFAULT.named_retransmission_interval",
108 9 : opt::value<uint16_t>()->default_value(1000),
109 : "Retranmission interval in msec")
110 :
111 9 : ("DEFAULT.hostip", opt::value<string>()->default_value(host_ip),
112 : "IP address of DNS Server")
113 9 : ("DEFAULT.hostname", opt::value<string>()->default_value(hostname),
114 : "Hostname of DNS Server")
115 18 : ("DEFAULT.http_server_port",
116 9 : opt::value<uint16_t>()->default_value(default_http_server_port),
117 : "Sandesh HTTP listener port")
118 18 : ("DEFAULT.dns_server_port",
119 9 : opt::value<uint16_t>()->default_value(default_dns_server_port),
120 : "DNS server port")
121 :
122 18 : ("DEFAULT.log_category",
123 9 : opt::value<string>()->default_value(log_category_),
124 : "Category filter for local logging of sandesh messages")
125 9 : ("DEFAULT.log_disable", opt::bool_switch(&log_disable_),
126 : "Disable sandesh logging")
127 18 : ("DEFAULT.log_property_file", opt::value<string>()->default_value(""),
128 : "log4cplus property file name")
129 18 : ("DEFAULT.log_file", opt::value<string>()->default_value("<stdout>"),
130 : "Filename for the logs to be written to")
131 18 : ("DEFAULT.log_files_count",
132 9 : opt::value<int>()->default_value(10),
133 : "Maximum log file roll over index")
134 18 : ("DEFAULT.log_file_size",
135 9 : opt::value<long>()->default_value(1024*1024),
136 : "Maximum size of the log file")
137 18 : ("DEFAULT.log_level", opt::value<string>()->default_value("SYS_NOTICE"),
138 : "Severity level for local logging of sandesh messages")
139 9 : ("DEFAULT.log_local", opt::bool_switch(&log_local_),
140 : "Enable local logging of sandesh messages")
141 9 : ("DEFAULT.use_syslog", opt::bool_switch(&use_syslog_),
142 : "Enable logging to syslog")
143 18 : ("DEFAULT.syslog_facility", opt::value<string>()->default_value("LOG_LOCAL0"),
144 : "Syslog facility to receive log lines")
145 9 : ("DEFAULT.test_mode", opt::bool_switch(&test_mode_),
146 : "Enable dns to run in test-mode")
147 :
148 18 : ("CONFIGDB.config_db_server_list",
149 9 : opt::value<vector<string> >()->default_value(
150 : default_config_db_server_list, default_config_db_server),
151 : "Config database server list")
152 18 : ("CONFIGDB.config_db_username",
153 18 : opt::value<string>()->default_value(""),
154 : "ConfigDB user")
155 18 : ("CONFIGDB.config_db_password",
156 18 : opt::value<string>()->default_value(""),
157 : "ConfigDB password")
158 18 : ("CONFIGDB.config_db_use_ssl",
159 9 : opt::value<bool>()->default_value(false),
160 : "Use SSL for Cassandra connection")
161 18 : ("CONFIGDB.config_db_ca_certs",
162 18 : opt::value<string>()->default_value(""),
163 : "CA Certificate file for SSL Cassandra connection")
164 18 : ("CONFIGDB.rabbitmq_server_list",
165 9 : opt::value<vector<string> >()->default_value(
166 : default_rabbitmq_server_list, default_rabbitmq_server),
167 : "RabbitMQ server list")
168 18 : ("CONFIGDB.rabbitmq_user",
169 18 : opt::value<string>()->default_value("guest"),
170 : "RabbitMQ user")
171 18 : ("CONFIGDB.rabbitmq_password",
172 18 : opt::value<string>()->default_value("guest"),
173 : "RabbitMQ password")
174 18 : ("CONFIGDB.rabbitmq_vhost",
175 18 : opt::value<string>()->default_value(""),
176 : "RabbitMQ vhost")
177 18 : ("CONFIGDB.rabbitmq_use_ssl",
178 9 : opt::value<bool>()->default_value(false),
179 : "Use SSL for RabbitMQ connection")
180 18 : ("CONFIGDB.rabbitmq_ssl_version",
181 18 : opt::value<string>()->default_value(""),
182 : "SSL version for RabbitMQ connection")
183 18 : ("CONFIGDB.rabbitmq_ssl_keyfile",
184 18 : opt::value<string>()->default_value(""),
185 : "Keyfile for SSL RabbitMQ connection")
186 18 : ("CONFIGDB.rabbitmq_ssl_certfile",
187 18 : opt::value<string>()->default_value(""),
188 : "Certificate file for SSL RabbitMQ connection")
189 18 : ("CONFIGDB.rabbitmq_ssl_ca_certs",
190 18 : opt::value<string>()->default_value(""),
191 : "CA Certificate file for SSL RabbitMQ connection")
192 :
193 9 : ("DEFAULT.xmpp_dns_auth_enable", opt::bool_switch(&xmpp_auth_enable_),
194 : "Enable authentication over Xmpp")
195 18 : ("DEFAULT.xmpp_server_cert",
196 18 : opt::value<string>()->default_value(
197 : "/etc/contrail/ssl/certs/server.pem"),
198 : "XMPP Server ssl certificate")
199 18 : ("DEFAULT.xmpp_server_key",
200 18 : opt::value<string>()->default_value(
201 : "/etc/contrail/ssl/private/server-privkey.pem"),
202 : "XMPP Server ssl private key")
203 9 : ("DEFAULT.xmpp_ca_cert",
204 9 : opt::value<string>()->default_value(
205 : "/etc/contrail/ssl/certs/ca-cert.pem"),
206 : "XMPP CA ssl certificate")
207 : ;
208 :
209 9 : sandesh::options::AddOptions(&config, &sandesh_config_);
210 :
211 9 : config_file_options_.add(config);
212 9 : cmdline_options.add(generic).add(config);
213 9 : }
214 :
215 27 : uint32_t Options::GenerateHash(const std::vector<std::string> &list) {
216 27 : std::string concat_servers;
217 27 : std::vector<std::string>::const_iterator iter;
218 64 : for (iter = list.begin(); iter != list.end(); iter++) {
219 37 : concat_servers += *iter;
220 : }
221 : boost::hash<std::string> string_hash;
222 54 : return(string_hash(concat_servers));
223 27 : }
224 :
225 9 : uint32_t Options::GenerateHash(const ConfigClientOptions &config) {
226 9 : uint32_t chk_sum = GenerateHash(config.config_db_server_list);
227 9 : chk_sum += GenerateHash(config.rabbitmq_server_list);
228 : boost::hash<std::string> string_hash;
229 9 : chk_sum += string_hash(config.rabbitmq_user);
230 9 : chk_sum += string_hash(config.rabbitmq_password);
231 9 : chk_sum += string_hash(config.config_db_username);
232 9 : chk_sum += string_hash(config.config_db_password);
233 9 : return chk_sum;
234 : }
235 :
236 : // Process command line options. They can come from a conf file as well. Options
237 : // from command line always overrides those that come from the config file.
238 9 : void Options::Process(int argc, char *argv[],
239 : opt::options_description &cmdline_options) {
240 : // Process options off command line first.
241 9 : opt::variables_map var_map;
242 9 : opt::store(opt::parse_command_line(argc, argv, cmdline_options), var_map);
243 :
244 : // Process options off configuration file.
245 9 : GetOptValue<string>(var_map, config_file_, "conf_file");
246 9 : ifstream config_file_in;
247 9 : config_file_in.open(config_file_.c_str());
248 9 : if (config_file_in.good()) {
249 7 : opt::store(opt::parse_config_file(config_file_in, config_file_options_),
250 : var_map);
251 : }
252 9 : config_file_in.close();
253 :
254 9 : opt::notify(var_map);
255 :
256 9 : if (var_map.count("help")) {
257 0 : cout << cmdline_options << endl;
258 0 : exit(0);
259 : }
260 :
261 9 : if (var_map.count("version")) {
262 0 : cout << BuildInfo << endl;
263 0 : exit(0);
264 : }
265 :
266 : // Retrieve the options.
267 9 : GetOptValue<string>(var_map, dns_config_file_, "DEFAULT.dns_config_file");
268 9 : GetOptValue< vector<string> >(var_map, collector_server_list_,
269 : "DEFAULT.collectors");
270 9 : collectors_configured_ = collector_server_list_.size();
271 15 : if (collector_server_list_.size() == 1 &&
272 6 : !collector_server_list_[0].compare(default_collector_server_list_[0])) {
273 6 : collectors_configured_ = false;
274 : }
275 :
276 : // Randomize Collector List
277 9 : collector_chksum_ = GenerateHash(collector_server_list_);
278 9 : randomized_collector_server_list_ = collector_server_list_;
279 9 : std::random_shuffle(randomized_collector_server_list_.begin(),
280 : randomized_collector_server_list_.end());
281 :
282 9 : GetOptValue<string>(var_map, named_config_file_,
283 : "DEFAULT.named_config_file");
284 9 : GetOptValue<string>(var_map, named_config_dir_,
285 : "DEFAULT.named_config_directory");
286 9 : GetOptValue<string>(var_map, named_log_file_, "DEFAULT.named_log_file");
287 9 : GetOptValue<string>(var_map, rndc_config_file_, "DEFAULT.rndc_config_file");
288 9 : GetOptValue<string>(var_map, rndc_secret_, "DEFAULT.rndc_secret");
289 9 : GetOptValue<string>(var_map, named_max_cache_size_,
290 : "DEFAULT.named_max_cache_size");
291 9 : GetOptValue<uint16_t>(var_map, named_max_retransmissions_,
292 : "DEFAULT.named_max_retransmissions");
293 9 : GetOptValue<uint16_t>(var_map, named_retransmission_interval_,
294 : "DEFAULT.named_retransmission_interval");
295 :
296 9 : GetOptValue<string>(var_map, host_ip_, "DEFAULT.hostip");
297 9 : GetOptValue<string>(var_map, hostname_, "DEFAULT.hostname");
298 :
299 9 : GetOptValue<uint16_t>(var_map, http_server_port_,
300 : "DEFAULT.http_server_port");
301 :
302 9 : GetOptValue<uint16_t>(var_map, dns_server_port_, "DEFAULT.dns_server_port");
303 :
304 9 : GetOptValue<string>(var_map, log_category_, "DEFAULT.log_category");
305 9 : GetOptValue<string>(var_map, log_file_, "DEFAULT.log_file");
306 9 : GetOptValue<string>(var_map, log_property_file_,
307 : "DEFAULT.log_property_file");
308 9 : GetOptValue<int>(var_map, log_files_count_, "DEFAULT.log_files_count");
309 9 : GetOptValue<long>(var_map, log_file_size_, "DEFAULT.log_file_size");
310 9 : GetOptValue<string>(var_map, log_level_, "DEFAULT.log_level");
311 9 : GetOptValue<bool>(var_map, use_syslog_, "DEFAULT.use_syslog");
312 9 : GetOptValue<string>(var_map, syslog_facility_, "DEFAULT.syslog_facility");
313 9 : GetOptValue<uint32_t>(var_map, send_ratelimit_,
314 : "DEFAULT.sandesh_send_rate_limit");
315 18 : GetOptValue< vector<string> >(var_map,
316 9 : configdb_options_.config_db_server_list,
317 : "CONFIGDB.config_db_server_list");
318 18 : GetOptValue<string>(var_map,
319 9 : configdb_options_.config_db_username,
320 : "CONFIGDB.config_db_username");
321 18 : GetOptValue<string>(var_map,
322 9 : configdb_options_.config_db_password,
323 : "CONFIGDB.config_db_password");
324 18 : GetOptValue<bool>(var_map,
325 9 : configdb_options_.config_db_use_ssl,
326 : "CONFIGDB.config_db_use_ssl");
327 18 : GetOptValue<string>(var_map,
328 9 : configdb_options_.config_db_ca_certs,
329 : "CONFIGDB.config_db_ca_certs");
330 18 : GetOptValue< vector<string> >(var_map,
331 9 : configdb_options_.rabbitmq_server_list,
332 : "CONFIGDB.rabbitmq_server_list");
333 18 : GetOptValue<string>(var_map,
334 9 : configdb_options_.rabbitmq_user,
335 : "CONFIGDB.rabbitmq_user");
336 18 : GetOptValue<string>(var_map,
337 9 : configdb_options_.rabbitmq_password,
338 : "CONFIGDB.rabbitmq_password");
339 18 : GetOptValue<string>(var_map,
340 9 : configdb_options_.rabbitmq_vhost,
341 : "CONFIGDB.rabbitmq_vhost");
342 18 : GetOptValue<bool>(var_map,
343 9 : configdb_options_.rabbitmq_use_ssl,
344 : "CONFIGDB.rabbitmq_use_ssl");
345 18 : GetOptValue<string>(var_map,
346 9 : configdb_options_.rabbitmq_ssl_version,
347 : "CONFIGDB.rabbitmq_ssl_version");
348 18 : GetOptValue<string>(var_map,
349 9 : configdb_options_.rabbitmq_ssl_keyfile,
350 : "CONFIGDB.rabbitmq_ssl_keyfile");
351 18 : GetOptValue<string>(var_map,
352 9 : configdb_options_.rabbitmq_ssl_certfile,
353 : "CONFIGDB.rabbitmq_ssl_certfile");
354 18 : GetOptValue<string>(var_map,
355 9 : configdb_options_.rabbitmq_ssl_ca_certs,
356 : "CONFIGDB.rabbitmq_ssl_ca_certs");
357 9 : ParseConfigOptions(var_map);
358 :
359 9 : GetOptValue<bool>(var_map, xmpp_auth_enable_, "DEFAULT.xmpp_dns_auth_enable");
360 9 : GetOptValue<string>(var_map, xmpp_server_cert_, "DEFAULT.xmpp_server_cert");
361 9 : GetOptValue<string>(var_map, xmpp_server_key_, "DEFAULT.xmpp_server_key");
362 9 : GetOptValue<string>(var_map, xmpp_ca_cert_, "DEFAULT.xmpp_ca_cert");
363 :
364 9 : sandesh::options::ProcessOptions(var_map, &sandesh_config_);
365 9 : }
366 :
367 0 : void Options::ParseReConfig() {
368 : // ReParse the filtered config params
369 0 : opt::variables_map var_map;
370 0 : ifstream config_file_in;
371 0 : config_file_in.open(config_file_.c_str());
372 0 : if (config_file_in.good()) {
373 0 : opt::store(opt::parse_config_file(config_file_in, config_file_options_),
374 : var_map);
375 : }
376 0 : config_file_in.close();
377 :
378 0 : collector_server_list_.clear();
379 0 : GetOptValue< vector<string> >(var_map, collector_server_list_,
380 : "DEFAULT.collectors");
381 :
382 0 : uint32_t new_chksum = GenerateHash(collector_server_list_);
383 0 : if (collector_chksum_ != new_chksum) {
384 0 : collector_chksum_ = new_chksum;
385 :
386 0 : randomized_collector_server_list_.clear();
387 0 : randomized_collector_server_list_ = collector_server_list_;
388 0 : std::random_shuffle(randomized_collector_server_list_.begin(),
389 : randomized_collector_server_list_.end());
390 : }
391 : // ReConnect Collectors irrespective of change list to achieve
392 : // rebalance when older collector nodes are up again.
393 0 : Sandesh::ReConfigCollectors(randomized_collector_server_list_);
394 :
395 0 : uint32_t old_config_chksum = configdb_chksum_;
396 0 : ParseConfigOptions(var_map);
397 0 : if ((old_config_chksum != configdb_chksum_) && config_client_manager_) {
398 0 : config_client_manager_->ReinitConfigClient(configdb_options());
399 : }
400 0 : }
401 :
402 9 : void Options::ParseConfigOptions(const boost::program_options::variables_map
403 : &var_map) {
404 9 : configdb_options_.config_db_server_list.clear();
405 18 : GetOptValue< vector<string> >(var_map,
406 9 : configdb_options_.config_db_server_list,
407 : "CONFIGDB.config_db_server_list");
408 18 : GetOptValue<string>(var_map,
409 9 : configdb_options_.config_db_username,
410 : "CONFIGDB.config_db_username");
411 18 : GetOptValue<string>(var_map,
412 9 : configdb_options_.config_db_password,
413 : "CONFIGDB.config_db_password");
414 18 : GetOptValue<bool>(var_map,
415 9 : configdb_options_.config_db_use_ssl,
416 : "CONFIGDB.config_db_use_ssl");
417 18 : GetOptValue<string>(var_map,
418 9 : configdb_options_.config_db_ca_certs,
419 : "CONFIGDB.config_db_ca_certs");
420 9 : configdb_options_.rabbitmq_server_list.clear();
421 18 : GetOptValue< vector<string> >(var_map,
422 9 : configdb_options_.rabbitmq_server_list,
423 : "CONFIGDB.rabbitmq_server_list");
424 18 : GetOptValue<string>(var_map,
425 9 : configdb_options_.rabbitmq_user,
426 : "CONFIGDB.rabbitmq_user");
427 18 : GetOptValue<string>(var_map,
428 9 : configdb_options_.rabbitmq_password,
429 : "CONFIGDB.rabbitmq_password");
430 18 : GetOptValue<string>(var_map,
431 9 : configdb_options_.rabbitmq_vhost,
432 : "CONFIGDB.rabbitmq_vhost");
433 18 : GetOptValue<bool>(var_map,
434 9 : configdb_options_.rabbitmq_use_ssl,
435 : "CONFIGDB.rabbitmq_use_ssl");
436 18 : GetOptValue<string>(var_map,
437 9 : configdb_options_.rabbitmq_ssl_version,
438 : "CONFIGDB.rabbitmq_ssl_version");
439 18 : GetOptValue<string>(var_map,
440 9 : configdb_options_.rabbitmq_ssl_keyfile,
441 : "CONFIGDB.rabbitmq_ssl_keyfile");
442 18 : GetOptValue<string>(var_map,
443 9 : configdb_options_.rabbitmq_ssl_certfile,
444 : "CONFIGDB.rabbitmq_ssl_certfile");
445 18 : GetOptValue<string>(var_map,
446 9 : configdb_options_.rabbitmq_ssl_ca_certs,
447 : "CONFIGDB.rabbitmq_ssl_ca_certs");
448 9 : configdb_chksum_ = GenerateHash(configdb_options_);
449 9 : }
|