From 5a1ef608928f2e1b52622fbf89fef2a81930c90a Mon Sep 17 00:00:00 2001 From: Yuvaraja Mariappan Date: Mon, 16 May 2016 11:33:24 -0700 Subject: [PATCH] SSL parameter setting in haproxy 1. lbaas_auth_conf param is added in agent which contains the credentials to fetch the ssl certificates and private-keys. if it is not mentioned, netns would use /etc/contrail/contrail-lbaas-auth.conf as default 2. when two netns is launched by agent continosly [without any delay] the second netns may report "LBAAS type is missing" if the first netns moves the conf file to haproxy dir which is fixed 3. issue is fixed during the agent restart. Change-Id: I511f21be1690364657f1bae3cb79608669cd5a18 Partial-Bug: 1569033 Closes-Bug: 1581154 --- src/vnsw/agent/init/agent_param.cc | 7 +++- src/vnsw/agent/init/agent_param.h | 4 ++ src/vnsw/agent/oper/instance_manager.cc | 11 ++++- src/vnsw/agent/oper/netns_instance_adapter.cc | 8 ++++ .../cert_mgr/barbican_cert_manager.py | 16 ++++--- .../haproxy_process.py | 42 +++++++++++++------ .../vrouter_netns.py | 27 ++++-------- 7 files changed, 76 insertions(+), 39 deletions(-) diff --git a/src/vnsw/agent/init/agent_param.cc b/src/vnsw/agent/init/agent_param.cc index 8396b3479a3..37bf3e9dd08 100644 --- a/src/vnsw/agent/init/agent_param.cc +++ b/src/vnsw/agent/init/agent_param.cc @@ -603,6 +603,8 @@ void AgentParam::ParseServiceInstance() { "SERVICE-INSTANCE.lb_ssl_cert_path"); GetValueFromTree(si_lb_keystone_auth_conf_path_, "SERVICE-INSTANCE.lb_keystone_auth_conf_path"); + GetValueFromTree(si_lbaas_auth_conf_, + "SERVICE-INSTANCE.lbaas_auth_conf"); } void AgentParam::ParseNexthopServer() { @@ -830,6 +832,8 @@ void AgentParam::ParseServiceInstanceArguments GetOptValue(var_map, si_netns_timeout_, "SERVICE-INSTANCE.netns_timeout"); GetOptValue(var_map, si_lb_ssl_cert_path_, "SERVICE-INSTANCE.lb_ssl_cert_path"); + GetOptValue(var_map, si_lbaas_auth_conf_, + "SERVICE-INSTANCE.lbaas_auth_conf"); } @@ -1229,6 +1233,7 @@ void AgentParam::LogConfig() const { LOG(DEBUG, "Service instance workers : " << si_netns_workers_); LOG(DEBUG, "Service instance timeout : " << si_netns_timeout_); LOG(DEBUG, "Service instance lb ssl : " << si_lb_ssl_cert_path_); + LOG(DEBUG, "Service instance lbaas auth : " << si_lbaas_auth_conf_); LOG(DEBUG, "Bgp as a service port range : " << bgp_as_a_service_port_range_); if (hypervisor_mode_ == MODE_KVM) { LOG(DEBUG, "Hypervisor mode : kvm"); @@ -1326,7 +1331,7 @@ AgentParam::AgentParam(bool enable_flow_options, xmpp_dns_auth_enable_(false), simulate_evpn_tor_(false), si_netns_command_(), si_docker_command_(), si_netns_workers_(0), - si_netns_timeout_(0), si_lb_ssl_cert_path_(), + si_netns_timeout_(0), si_lb_ssl_cert_path_(), si_lbaas_auth_conf_(), vmware_mode_(ESXI_NEUTRON), nexthop_server_endpoint_(), nexthop_server_add_pid_(0), vrouter_on_nic_mode_(false), diff --git a/src/vnsw/agent/init/agent_param.h b/src/vnsw/agent/init/agent_param.h index 41dbf1020f5..eda99525f17 100644 --- a/src/vnsw/agent/init/agent_param.h +++ b/src/vnsw/agent/init/agent_param.h @@ -146,6 +146,9 @@ class AgentParam { std::string si_lb_keystone_auth_conf_path() const { return si_lb_keystone_auth_conf_path_; } + std::string si_lbaas_auth_conf() const { + return si_lbaas_auth_conf_; + } std::string nexthop_server_endpoint() const { return nexthop_server_endpoint_; @@ -470,6 +473,7 @@ class AgentParam { int si_netns_timeout_; std::string si_lb_ssl_cert_path_; std::string si_lb_keystone_auth_conf_path_; + std::string si_lbaas_auth_conf_; VmwareMode vmware_mode_; // List of IP addresses on the compute node. AddressList compute_node_address_list_; diff --git a/src/vnsw/agent/oper/instance_manager.cc b/src/vnsw/agent/oper/instance_manager.cc index a35554dd1e4..b58429e84c7 100644 --- a/src/vnsw/agent/oper/instance_manager.cc +++ b/src/vnsw/agent/oper/instance_manager.cc @@ -28,7 +28,7 @@ SandeshTraceBufferPtr InstanceManagerTraceBuf( SandeshTraceBufferCreate("InstanceManager", 1000)); static const char loadbalancer_config_path_default[] = - "/var/lib/contrail/"; + "/var/lib/contrail/loadbalancer/"; static const char namespace_store_path_default[] = "/var/run/netns"; static const char namespace_prefix[] = "vrouter-"; @@ -160,6 +160,15 @@ void InstanceManager::Initialize(DB *database, const std::string &netns_cmd, "in the config file, the Docker instances won't be started"); } + std::stringstream pathgen; + pathgen << loadbalancer_config_path_; + boost::filesystem::path dir(pathgen.str()); + boost::system::error_code error; + boost::filesystem::create_directories(dir, error); + if (error) { + LOG(ERROR, "Falied to create Loadbalancer Directory " << pathgen.str()); + } + adapters_.push_back(new DockerInstanceAdapter(docker_cmd, agent_)); adapters_.push_back(new NetNSInstanceAdapter(netns_cmd, loadbalancer_config_path_, agent_)); diff --git a/src/vnsw/agent/oper/netns_instance_adapter.cc b/src/vnsw/agent/oper/netns_instance_adapter.cc index 91a464cc84d..c9681a75d4e 100644 --- a/src/vnsw/agent/oper/netns_instance_adapter.cc +++ b/src/vnsw/agent/oper/netns_instance_adapter.cc @@ -69,6 +69,14 @@ InstanceTask* NetNSInstanceAdapter::CreateStartTask(const ServiceInstance::Prope fs << kvp.key << "::::" << kvp.value; kvp_found = true; } + if (!agent_->params()->si_lb_ssl_cert_path().empty()) { + fs << ":::::" << "lb_ssl_cert_path"; + fs << "::::" << agent_->params()->si_lb_ssl_cert_path(); + } + if (!agent_->params()->si_lbaas_auth_conf().empty()) { + fs << ":::::" << "lbaas_auth_conf"; + fs << "::::" << agent_->params()->si_lbaas_auth_conf(); + } fs.close(); if (kvp_found == false) { LOG(ERROR, "KeyValuePair is missing for loadbalancer: " diff --git a/src/vnsw/opencontrail-vrouter-netns/opencontrail_vrouter_netns/cert_mgr/barbican_cert_manager.py b/src/vnsw/opencontrail-vrouter-netns/opencontrail_vrouter_netns/cert_mgr/barbican_cert_manager.py index aa67f3d6817..f8d19ba9454 100644 --- a/src/vnsw/opencontrail-vrouter-netns/opencontrail_vrouter_netns/cert_mgr/barbican_cert_manager.py +++ b/src/vnsw/opencontrail-vrouter-netns/opencontrail_vrouter_netns/cert_mgr/barbican_cert_manager.py @@ -22,9 +22,13 @@ def __init__(self): self.region = 'RegionOne' self.session = {} - def parse_args(self): + def parse_args(self, auth_conf=None): config = ConfigParser.SafeConfigParser() - config.read('/etc/contrail/contrail-lbaas-auth.conf') + if (auth_conf): + self.auth_conf = auth_conf + else: + self.auth_conf = '/etc/contrail/contrail-lbaas-auth.conf' + config.read(self.auth_conf) self.admin_user = config.get('BARBICAN', 'admin_user') self.admin_password = config.get('BARBICAN', 'admin_password') @@ -47,11 +51,11 @@ def parse_args(self): except Exception: pass - def get_session(self): + def get_session(self, auth_conf=None): if self.session.get(self.project_name): return self.session[self.project_name] - self.parse_args() + self.parse_args(auth_conf) kwargs = {'auth_url': self.auth_url, 'username': self.admin_user, 'password': self.admin_password} @@ -210,9 +214,9 @@ def create_pem_file(barbican, url, dest_dir): f.close() return pem_file_name -def update_ssl_config(haproxy_config, dest_dir): +def update_ssl_config(haproxy_config, auth_conf, dest_dir): barb_auth = BarbicanKeystoneSession() - sess = barb_auth.get_session() + sess = barb_auth.get_session(auth_conf) if sess is None: return None barbican = client.Client(session=sess) diff --git a/src/vnsw/opencontrail-vrouter-netns/opencontrail_vrouter_netns/haproxy_process.py b/src/vnsw/opencontrail-vrouter-netns/opencontrail_vrouter_netns/haproxy_process.py index a122249fcce..23eeaa0a421 100644 --- a/src/vnsw/opencontrail-vrouter-netns/opencontrail_vrouter_netns/haproxy_process.py +++ b/src/vnsw/opencontrail-vrouter-netns/opencontrail_vrouter_netns/haproxy_process.py @@ -45,41 +45,57 @@ def create_haproxy_dir(base_dir, loadbalancer_id): p.communicate() return dir_name -def update_ssl_config(haproxy_config, dir_name): - config = ConfigParser.SafeConfigParser() - config.read('/etc/contrail/contrail-vrouter-agent.conf') - haproxy_ssl_cert_path = config.get('SERVICE-INSTANCE', 'haproxy_ssl_cert_path') +def update_ssl_config(haproxy_config, + haproxy_ssl_cert_path, dir_name): search_string = 'haproxy_ssl_cert_path' for line in haproxy_config.split('\n'): if search_string in line: - haproxy_config = haproxy_config.replace(search_string, haproxy_ssl_cert_path) + haproxy_config = haproxy_config.replace( + search_string, haproxy_ssl_cert_path) break return haproxy_config def get_haproxy_config_file(cfg_file, dir_name): - lb_version = '' - haproxy_config = '' f = open(cfg_file) content = f.read() f.close() + + lb_ssl_cert_path = '' + lbaas_auth_conf = '/etc/contrail/contrail-lbaas-auth.conf' kvps = content.split(':::::') for kvp in kvps or []: KeyValue = kvp.split('::::') - if (KeyValue[0] == 'lb_version'): + if (KeyValue[0] == 'lb_uuid'): + lb_uuid = KeyValue[1] + elif (KeyValue[0] == 'lb_version'): lb_version = KeyValue[1] elif (KeyValue[0] == 'haproxy_config'): haproxy_config = KeyValue[1] - if lb_version and haproxy_config: - break; - haproxy_cfg_file = dir_name + "/" + HAPROXY_PROCESS_CONF + elif (KeyValue[0] == 'lb_ssl_cert_path'): + lb_ssl_cert_path = KeyValue[1] + elif (KeyValue[0] == 'lbaas_auth_conf'): + lbaas_auth_conf = KeyValue[1] if 'ssl crt' in haproxy_config: if lb_version == 'v1': - haproxy_config = update_ssl_config(haproxy_config, dir_name); + if not (os.path.isfile(lb_ssl_cert_path)): + msg = "%s is missing for "\ + "Loadbalancer-ID %s" %(lb_ssl_cert_path, lb_uuid) + logging.error(msg) + return None + haproxy_config = update_ssl_config(haproxy_config, + lb_ssl_cert_path, dir_name); else: - haproxy_config = barbican_cert_mgr.update_ssl_config(haproxy_config, dir_name) + if not (os.path.isfile(lbaas_auth_conf)): + msg = "%s is missing for "\ + "Loadbalancer-ID %s" %(lbaas_auth_conf, lb_uuid) + logging.error(msg) + return None + haproxy_config = barbican_cert_mgr.update_ssl_config( + haproxy_config, lbaas_auth_conf, dir_name) if haproxy_config is None: return None + haproxy_cfg_file = dir_name + "/" + HAPROXY_PROCESS_CONF f = open(haproxy_cfg_file, 'w+') f.write(haproxy_config) f.close() diff --git a/src/vnsw/opencontrail-vrouter-netns/opencontrail_vrouter_netns/vrouter_netns.py b/src/vnsw/opencontrail-vrouter-netns/opencontrail_vrouter_netns/vrouter_netns.py index 0efa12f156c..b912933be44 100644 --- a/src/vnsw/opencontrail-vrouter-netns/opencontrail_vrouter_netns/vrouter_netns.py +++ b/src/vnsw/opencontrail-vrouter-netns/opencontrail_vrouter_netns/vrouter_netns.py @@ -150,19 +150,6 @@ def find_lbaas_type(self, cfg_file): break; return lbaas_type - def move_cfg_file_to_lbaas_dir(self, cfg_file): - dir_name = self.LBAAS_DIR; - if not os.path.exists(dir_name): - cmd = "mkdir -p " + dir_name - cmd_list = shlex.split(cmd) - p = subprocess.Popen(cmd_list) - p.communicate() - cmd = "mv " + cfg_file + " " + dir_name - cmd_list = shlex.split(cmd) - p = subprocess.Popen(cmd_list) - p.communicate(); - return dir_name + '/' + os.path.basename(cfg_file) - def remove_cfg_file(self, cfg_file): cmd = "rm " + cfg_file cmd_list = shlex.split(cmd) @@ -173,10 +160,13 @@ def set_lbaas(self): if not self.ip_ns.netns.exists(self.namespace): self.create() + if not (os.path.isfile(self.cfg_file)): + msg = "%s is missing for "\ + "Loadbalancer-ID %s" %(self.cfg_file, self.loadbalancer_id) + raise ValueError(msg) lbaas_type = self.find_lbaas_type(self.cfg_file) if (lbaas_type == ''): raise ValueError('LBAAS_TYPE does not exist %s' % self.cfg_file) - self.cfg_file = self.move_cfg_file_to_lbaas_dir(self.cfg_file) if (lbaas_type == 'haproxy_config'): ret = haproxy_process.start_update_haproxy( self.loadbalancer_id, self.cfg_file, @@ -190,7 +180,7 @@ def set_lbaas(self): pass return True - def release_lbaas(self): + def release_lbaas(self, caller): if not self.ip_ns.netns.exists(self.namespace): raise ValueError('Need to create the network namespace before ' 'relasing lbaas') @@ -204,7 +194,8 @@ def release_lbaas(self): self.ip_ns.netns.execute(['route', 'del', 'default']) except RuntimeError: pass - self.remove_cfg_file(cfg_file) + if (caller == 'destroy'): + self.remove_cfg_file(cfg_file) def destroy(self): if not self.ip_ns.netns.exists(self.namespace): @@ -457,7 +448,7 @@ def create(self): # If the netns already exists, destroy it to be sure to set it # with new parameters like another external network if self.args.service_type == self.LOAD_BALANCER: - netns_mgr.release_lbaas() + netns_mgr.release_lbaas('create') netns_mgr.unplug_namespace_interface() netns_mgr.destroy() netns_mgr.create() @@ -495,7 +486,7 @@ def destroy(self): if self.args.service_type == self.SOURCE_NAT: netns_mgr.destroy() elif self.args.service_type == self.LOAD_BALANCER: - netns_mgr.release_lbaas() + netns_mgr.release_lbaas('destroy') netns_mgr.destroy() else: msg = ('The %s service type is not supported' %