LCOV - code coverage report
Current view: top level - control-node - options.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 205 238 86.1 %
Date: 2026-11-09 02:10:49 Functions: 7 8 87.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14