Skip to content

Commit

Permalink
SSL parameter setting in haproxy
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ymariappan committed May 17, 2016
1 parent 12325b9 commit 5a1ef60
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 39 deletions.
7 changes: 6 additions & 1 deletion src/vnsw/agent/init/agent_param.cc
Expand Up @@ -603,6 +603,8 @@ void AgentParam::ParseServiceInstance() {
"SERVICE-INSTANCE.lb_ssl_cert_path");
GetValueFromTree<string>(si_lb_keystone_auth_conf_path_,
"SERVICE-INSTANCE.lb_keystone_auth_conf_path");
GetValueFromTree<string>(si_lbaas_auth_conf_,
"SERVICE-INSTANCE.lbaas_auth_conf");
}

void AgentParam::ParseNexthopServer() {
Expand Down Expand Up @@ -830,6 +832,8 @@ void AgentParam::ParseServiceInstanceArguments
GetOptValue<int>(var_map, si_netns_timeout_, "SERVICE-INSTANCE.netns_timeout");
GetOptValue<string>(var_map, si_lb_ssl_cert_path_,
"SERVICE-INSTANCE.lb_ssl_cert_path");
GetOptValue<string>(var_map, si_lbaas_auth_conf_,
"SERVICE-INSTANCE.lbaas_auth_conf");

}

Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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),
Expand Down
4 changes: 4 additions & 0 deletions src/vnsw/agent/init/agent_param.h
Expand Up @@ -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_;
Expand Down Expand Up @@ -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_;
Expand Down
11 changes: 10 additions & 1 deletion src/vnsw/agent/oper/instance_manager.cc
Expand Up @@ -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-";
Expand Down Expand Up @@ -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_));
Expand Down
8 changes: 8 additions & 0 deletions src/vnsw/agent/oper/netns_instance_adapter.cc
Expand Up @@ -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: "
Expand Down
Expand Up @@ -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')
Expand All @@ -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}
Expand Down Expand Up @@ -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)
Expand Down
Expand Up @@ -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()
Expand Down
Expand Up @@ -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)
Expand All @@ -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,
Expand All @@ -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')
Expand All @@ -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):
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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' %
Expand Down

0 comments on commit 5a1ef60

Please sign in to comment.