Skip to content

Commit

Permalink
Remove some unnecessary options and rename some options pertaining to…
Browse files Browse the repository at this point in the history
… tor_agent provisioning from testbed file.

Removed standby_tor_agent_ip, standby_tor_agent_tor_id and standby_tor_agent_tor_ovs_port options from testbed.py file. Redundant TOR Agent is identified by its 'tor_name'. Two TOR Agents which need to be redundant to each other should have the same 'tor_name' configured. They should also have the same 'tor_ovs_port" configured.
Also renamed tor_id to tor_agent_id and tor_http_server_port to tor_agent_http_server_port
Also made ca_cert_file as global parameter instead of per tor-agent parameter

Closes-Bug: #1458502
(cherry picked from commit 9804fd3)

Change-Id: If5d720e7c0b3100995245034dd63775bacd3c40c
  • Loading branch information
ashoksr committed Jun 9, 2015
1 parent 24c7622 commit 0248cfc
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 73 deletions.
170 changes: 119 additions & 51 deletions fabfile/tasks/provision.py
Expand Up @@ -142,7 +142,7 @@ def fixup_restart_haproxy_in_all_cfgm(nworkers):

# create TOR agent configuration for the HA proxy
if 'toragent' in env.roledefs.keys() and 'tor_agent' in env.keys():
tor_agent_ha_config = get_all_tor_agent_haproxy_config(env.roledefs['toragent'])
tor_agent_ha_config = get_all_tor_agent_haproxy_config()

for host_string in env.roledefs['cfgm']:
haproxy_config = template.safe_substitute({
Expand Down Expand Up @@ -180,34 +180,96 @@ def fixup_restart_haproxy_in_all_cfgm(nworkers):
# end fixup_restart_haproxy_in_all_cfgm

# Get HA proxy configuration for a TOR agent
def get_tor_agent_haproxy_config(proxy_name, proxy_port, ip1, port1, ip2, port2):
def get_tor_agent_haproxy_config(proxy_name, key, ha_dict):
tor_agent_ha_config = '\n'
tor_agent_ha_config = tor_agent_ha_config + 'listen %s :%s\n' %(proxy_name, str(proxy_port))
port_list = ha_dict[key]
ha_dict_len = len(port_list)
if ha_dict_len == 0:
return tor_agent_ha_config
ip2 = None
if "-" in key:
ip1 = key.split('-')[0]
ip2 = key.split('-')[1]
else:
ip1 = key
tor_agent_ha_config = tor_agent_ha_config + 'listen %s\n' %(proxy_name)
tor_agent_ha_config = tor_agent_ha_config + ' mode tcp\n'
tor_agent_ha_config = tor_agent_ha_config + ' server %s %s:%s\n' %(ip1, ip1, str(port1))
tor_agent_ha_config = tor_agent_ha_config + ' server %s %s:%s\n' %(ip2, ip2, str(port2))
tor_agent_ha_config = tor_agent_ha_config + ' bind :%s' %(port_list[0])
for i in range(1, ha_dict_len):
tor_agent_ha_config = tor_agent_ha_config + ',:%s' %(port_list[i])
tor_agent_ha_config = tor_agent_ha_config + '\n'
tor_agent_ha_config = tor_agent_ha_config + ' server %s %s\n' %(ip1, ip1)
if ip2 != None:
tor_agent_ha_config = tor_agent_ha_config + ' server %s %s\n' %(ip2, ip2)
tor_agent_ha_config = tor_agent_ha_config + ' balance leastconn\n'
tor_agent_ha_config = tor_agent_ha_config + '\n'
return tor_agent_ha_config
#end get_tor_agent_haproxy_config

def get_tor_agent_id(entry):
tor_id = -1
if 'tor_id' in entry:
tor_id= int(entry['tor_id'])
elif 'tor_agent_id' in entry:
tor_id= int(entry['tor_agent_id'])
else:
print 'tor-agent-id configuration is missing in testbed file'
return tor_id
#end get_tor_agent_id

# Given a host_string and tor_name, return the standby tor-agent info identified
# by index and host-string of tor-agent
def get_standby_info(skip_host, match_tor_name):
toragent_dict = getattr(env,'tor_agent', None)
tor_agent_host_list = get_toragent_nodes()
for host in tor_agent_host_list:
if host == skip_host:
continue
for i in range(len(toragent_dict[host])):
tor_name= toragent_dict[host][i]['tor_name']
if tor_name == match_tor_name:
return (i, host)
return (-1, None)
#end get_standby_info

def make_key(tsn1, tsn2):
if tsn1 < tsn2:
return tsn1 + "-" + tsn2
return tsn2 + "-" + tsn1

# Get HA proxy configuration for all TOR agents
def get_all_tor_agent_haproxy_config(*args):
tor_agent_ha_config = ''
for host_list in args:
for host_string in host_list:
with settings(host_string=host_string):
toragent_dict = getattr(env, 'tor_agent', None)
for i in range(len(toragent_dict[host_string])):
if 'standby_tor_agent_ip' in toragent_dict[host_string][i] and \
'standby_tor_agent_tor_ovs_port' in toragent_dict[host_string][i]:
proxy_name = 'contrail-tor-agent-' + toragent_dict[host_string][i]['tor_id']
ip1=hstr_to_ip(get_control_host_string(host_string))
port1 = int(toragent_dict[host_string][i]['tor_ovs_port'])
ip2 = toragent_dict[host_string][i]['standby_tor_agent_ip']
port2 = int(toragent_dict[host_string][i]['standby_tor_agent_tor_ovs_port'])
tor_agent_ha_config = tor_agent_ha_config + get_tor_agent_haproxy_config(proxy_name, port1, ip1, port1, ip2, port2)
return tor_agent_ha_config
#end get_all_tor_agent_haproxy_config
def get_all_tor_agent_haproxy_config():
toragent_dict = getattr(env,'tor_agent', None)
master_standby_dict = {}
tor_agent_host_list = get_toragent_nodes()
for host in tor_agent_host_list:
for i in range(len(toragent_dict[host])):
tor_name= toragent_dict[host][i]['tor_name']
tsn1 = toragent_dict[host][i]['tor_tsn_ip']
port1 = toragent_dict[host][i]['tor_ovs_port']
standby_tor_idx, standby_host = get_standby_info(host, tor_name)
key = tsn1
if (standby_tor_idx != -1 and standby_host != None):
tsn2 = toragent_dict[standby_host][standby_tor_idx]['tor_tsn_ip']
port2 = toragent_dict[standby_host][standby_tor_idx]['tor_ovs_port']
if port1 == port2:
key = make_key(tsn1, tsn2)
else:
print "Tor Agents (%s, %d) and (%s, %d) are configured as \
redundant agents but don't have same ovs_port" \
%(host, i, standby_host, standby_tor_idx)
if not key in master_standby_dict:
master_standby_dict[key] = []
if not port1 in master_standby_dict[key]:
master_standby_dict[key].append(port1)
i = 1
cfg_str = ""
for key in master_standby_dict.keys():
proxy_name = "contrail-tor-agent-" + str(i)
i = i + 1
cfg_str = cfg_str + get_tor_agent_haproxy_config(proxy_name, key, master_standby_dict)
return cfg_str
#end test_task

@roles('cfgm')
@task
Expand Down Expand Up @@ -1721,13 +1783,22 @@ def add_tor_agent_by_index(index, node_info, restart=True):
with settings(host_string=host_string):
toragent_dict = getattr(env,'tor_agent', None)
# Populate the argument to pass for setup-vnc-tor-agent
tor_id= int(toragent_dict[host_string][i]['tor_id'])
tor_id = int(get_tor_agent_id(toragent_dict[host_string][i]))
if tor_id == -1:
return
tor_name= toragent_dict[host_string][i]['tor_name']
tor_tunnel_ip= toragent_dict[host_string][i]['tor_tunnel_ip']
tor_vendor_name= toragent_dict[host_string][i]['tor_vendor_name']
tsn_name=toragent_dict[host_string][i]['tor_tsn_name']
tor_mgmt_ip=toragent_dict[host_string][i]['tor_ip']
http_server_port = toragent_dict[host_string][i]['tor_http_server_port']
http_server_port = -1
if 'tor_http_server_port' in toragent_dict[host_string][i]:
http_server_port = toragent_dict[host_string][i]['tor_http_server_port']
elif 'tor_agent_http_server_port' in toragent_dict[host_string][i]:
http_server_port = toragent_dict[host_string][i]['tor_agent_http_server_port']
if http_server_port == -1:
print 'tor_agent_http_server_port configuration is missing in testbed file'
return
tgt_hostname = sudo("hostname")
tor_agent_host = get_control_host_string(host_string)
tor_agent_control_ip= hstr_to_ip(tor_agent_host)
Expand Down Expand Up @@ -1761,33 +1832,28 @@ def add_tor_agent_by_index(index, node_info, restart=True):
domain_name = sudo("domainname -f")
cert_file = "/etc/contrail/ssl/certs/tor." + str(tor_id) + ".cert.pem"
privkey_file = "/etc/contrail/ssl/private/tor." + str(tor_id) + ".privkey.pem"
ssl_files_copied_from_standby = False

# when we have HA configured for the agent, ensure that both
# TOR agents use same SSL certificates. Copy the files
# created on standby, if they are already created. Otherwise
# generate the files.
if 'standby_tor_agent_ip' in toragent_dict[host_string][i] and \
'standby_tor_agent_tor_id' in toragent_dict[host_string][i]:
for node in env.roledefs['all']:
if hstr_to_ip(get_control_host_string(node)) == toragent_dict[host_string][i]['standby_tor_agent_ip']:
ha_tor_id = str(toragent_dict[host_string][i]['standby_tor_agent_tor_id'])
cert_ha_file = '/etc/contrail/ssl/certs/tor.' + ha_tor_id + '.cert.pem'
priv_ha_file = '/etc/contrail/ssl/private/tor.' + ha_tor_id + '.privkey.pem'
temp_cert_file = tempfile.mktemp()
temp_priv_file = tempfile.mktemp()
with settings(host_string=node):
if exists(cert_ha_file, use_sudo=True) and exists(priv_ha_file, use_sudo=True):
get_as_sudo(cert_ha_file, temp_cert_file)
get_as_sudo(priv_ha_file, temp_priv_file)
if os.path.exists(temp_cert_file) and os.path.exists(temp_priv_file):
put(temp_cert_file, cert_file)
put(temp_priv_file, privkey_file)
os.remove(temp_cert_file)
os.remove(temp_priv_file)
ssl_files_copied_from_standby = True
break

ssl_files_copied_from_standby = False
standby_tor_idx, standby_host = get_standby_info(host_string, tor_name)
if (standby_tor_idx != -1 and standby_host != None):
ha_tor_id = str(get_tor_agent_id(toragent_dict[standby_host][standby_tor_idx]))
cert_ha_file = '/etc/contrail/ssl/certs/tor.' + ha_tor_id + '.cert.pem'
priv_ha_file = '/etc/contrail/ssl/private/tor.' + ha_tor_id + '.privkey.pem'
temp_cert_file = tempfile.mktemp()
temp_priv_file = tempfile.mktemp()
with settings(host_string=standby_host):
if exists(cert_ha_file, use_sudo=True) and exists(priv_ha_file, use_sudo=True):
get_as_sudo(cert_ha_file, temp_cert_file)
get_as_sudo(priv_ha_file, temp_priv_file)
if os.path.exists(temp_cert_file) and os.path.exists(temp_priv_file):
put(temp_cert_file, cert_file)
put(temp_priv_file, privkey_file)
os.remove(temp_cert_file)
os.remove(temp_priv_file)
ssl_files_copied_from_standby = True
# Generate files if we didn't copy from standby
if not ssl_files_copied_from_standby:
ssl_cmd = "openssl req -new -x509 -sha256 -newkey rsa:4096 -nodes -subj \"/C=US/ST=Global/L="
Expand All @@ -1796,9 +1862,9 @@ def add_tor_agent_by_index(index, node_info, restart=True):
sudo(ssl_cmd)

# if CA cert file is specified, copy it to the target
if 'ca_cert_file' in toragent_dict[host_string][i] and \
os.path.isfile(toragent_dict[host_string][i]['ca_cert_file']):
put(toragent_dict[host_string][i]['ca_cert_file'], '/etc/contrail/ssl/certs/cacert.pem')
ca_cert_file = getattr(env, 'ca_cert_file', None)
if ca_cert_file != None and os.path.isfile(ca_cert_file):
put(ca_cert_file, '/etc/contrail/ssl/certs/cacert.pem')

cfgm_host = get_control_host_string(env.roledefs['cfgm'][0])
cfgm_host_password = get_env_passwords(env.roledefs['cfgm'][0])
Expand Down Expand Up @@ -1903,7 +1969,9 @@ def delete_tor_agent_by_index(index, node_info, restart=True):
'testbed file' %(host_string, i)
return
# Populate the argument to pass for setup-vnc-tor-agent
tor_id= int(toragent_dict[host_string][i]['tor_id'])
tor_id = int(get_tor_agent_id(toragent_dict[host_string][i]))
if tor_id == -1:
return
tor_name= toragent_dict[host_string][i]['tor_name']
tor_vendor_name= toragent_dict[host_string][i]['tor_vendor_name']
tgt_hostname = sudo("hostname")
Expand Down
38 changes: 18 additions & 20 deletions fabfile/testbeds/testbed_multibox_example.py
Expand Up @@ -221,6 +221,13 @@
#To disable installing contrail interface rename package
#env.interface_rename = False


#Path where the CA certificate file is stored on the node where fab is run.
#Fab copies the file to node where TOR agent is run.
#This is optional and is required only when tor_ovs_protocol is pssl.
#The certificates on the TOR are based on this CA cert.
#env.ca_cert_file = '/root/file.pem'

#In environments where keystone is deployed outside of Contrail provisioning
#scripts , you can use the below options
#
Expand Down Expand Up @@ -365,30 +372,25 @@
#Definition for the Key used
#-------------------------------------
# tor_ip: IP of the tor switch
# tor_id: Unique Id of the tor switch to identify. Typicaly a numeric value.
# tor_agent_id: Unique Id of the tor switch to identify. Typicaly a numeric value.
# tor_agent_name: Unique name for TOR Agent. This is optional field. If this is
# not specified name used will be <hostname>-<tor_agent_id>
# tor_type: Always ovs
# tor_ovs_port: Port number to be used by ovs
# tor_ovs_port: Port number to be used by ovs. If any redundant TOR Agent is
# specified for this tor-agent, it should have the same 'tor_ovs_port'
# tor_ovs_protocol: Connection protocol between TOR Agent and TOR (tcp / pssl)
# tor_tsn_ip: TSN node ip
# tor_tsn_name: Name of the TSN node
# tor_name: Name of the tor switch
# tor_name: Name of the tor switch. If any redundant TOR Agent is specified for
# this tor-agent, it should have the same 'tor_name'
# tor_tunnel_ip: Data plane IP for the tor switch
# tor_vendor_name: Vendor type for TOR switch
# tor_http_server_port: HTTP server port. Same will be used by tor agent for introspect
# ca_cert_file: Path where the CA certificate file is stored on the node where fab is run.
# Fab copies the file to node where TOR agent is run.
# This is optional and is required only when tor_ovs_protocol is pssl.
# The certificates on the TOR are based on this CA cert.
# standby_tor_agent_ip: IP of the TOR agent where redundant TOR Agent will run.
# This is optional and is required only when tor_ovs_protocol is pssl.
# standby_tor_agent_tor_id: tor_id of the same TOR on the redundant node.
# This is optional and is required only when tor_ovs_protocol is pssl.
# standby_tor_agent_tor_ovs_port: Port number used for OVS by the redundant TOR agent.
# This is optional and is required only when tor_ovs_protocol is pssl.
# tor_agent_http_server_port: HTTP server port. Same will be used by tor agent for introspect
#
#env.tor_agent = {host10:[{
# 'tor_ip':'10.204.217.39',
# 'tor_id':'1',
# 'tor_agent_id':'1',
# 'tor_agent_name':'nodexx-1',
# 'tor_type':'ovs',
# 'tor_ovs_port':'9999',
# 'tor_ovs_protocol':'tcp',
Expand All @@ -397,11 +399,7 @@
# 'tor_name':'bng-contrail-qfx51-2',
# 'tor_tunnel_ip':'34.34.34.34',
# 'tor_vendor_name':'Juniper'
# 'tor_http_server_port': '9010',
# 'ca_cert_file':'/root/ca_cert.pem',
# 'standby_tor_agent_ip':'10.204.217.100',
# 'standby_tor_agent_tor_id':'1',
# 'standby_tor_agent_tor_ovs_port':'9888',
# 'tor_agent_http_server_port': '9010',
# }]
# }
#######################################
Expand Down
6 changes: 4 additions & 2 deletions fabfile/testbeds/testbed_singlebox_example.py
Expand Up @@ -295,12 +295,14 @@
#Definition for the Key used
#-------------------------------------
# tor_ip: IP of the tor switch
# tor_id: Unique Id of the tor switch to identify. Typicaly a numeric value.
# tor_agent_id: Unique Id of the tor switch to identify. Typicaly a numeric value.
# tor_agent_name: Unique name for TOR Agent. This is optional field. If this is
# not specified name used will be <hostname>-<tor_agent_id>
# tor_ovs_port: Port number to be used by ovs
# tor_ovs_protocol: Connection protocol to be used by ovs. Currently only TCP
# tor_tsn_ip: TSN node ip
#env.tor_agent =
#{host3:[{'tor_ip':'10.204.217.39','tor_id':'1','tor_ovs_port':'9999','tor_ovs_protocol':'tcp','tor_tsn_ip':'10.204.221.35'}]}
#{host3:[{'tor_ip':'10.204.217.39','tor_agent_id':'1','tor_agent_name':'nodexx-1', 'tor_ovs_port':'9999','tor_ovs_protocol':'tcp','tor_tsn_ip':'10.204.221.35'}]}

# OPTIONAL DPDK CONFIGURATION
# ===========================
Expand Down

0 comments on commit 0248cfc

Please sign in to comment.