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