From 9804fd3e10dfee6e772b6d0d0d806fc66b96e797 Mon Sep 17 00:00:00 2001 From: ashoksingh Date: Mon, 8 Jun 2015 10:52:35 +0530 Subject: [PATCH] Remove some unnecessary options and rename some options pertaining to 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 Change-Id: I8d9e427056d34157b8291a5a31de864615992849 Closes-Bug: #1458502 --- fabfile/tasks/provision.py | 170 ++++++++++++------ fabfile/testbeds/testbed_multibox_example.py | 38 ++-- fabfile/testbeds/testbed_singlebox_example.py | 6 +- 3 files changed, 141 insertions(+), 73 deletions(-) diff --git a/fabfile/tasks/provision.py b/fabfile/tasks/provision.py index 7e21dabe3..b24594d83 100644 --- a/fabfile/tasks/provision.py +++ b/fabfile/tasks/provision.py @@ -141,7 +141,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({ @@ -179,34 +179,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 @@ -1707,13 +1769,22 @@ def add_tor_agent_by_index(index, node_info, restart=True): 'in 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_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) @@ -1747,33 +1818,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=" @@ -1782,9 +1848,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]) @@ -1885,7 +1951,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") diff --git a/fabfile/testbeds/testbed_multibox_example.py b/fabfile/testbeds/testbed_multibox_example.py index f1ec93a03..c5da17310 100644 --- a/fabfile/testbeds/testbed_multibox_example.py +++ b/fabfile/testbeds/testbed_multibox_example.py @@ -222,6 +222,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 # @@ -366,30 +373,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 - # 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', @@ -398,11 +400,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', # }] # } ####################################### diff --git a/fabfile/testbeds/testbed_singlebox_example.py b/fabfile/testbeds/testbed_singlebox_example.py index 83d01f7ec..9a6b81198 100644 --- a/fabfile/testbeds/testbed_singlebox_example.py +++ b/fabfile/testbeds/testbed_singlebox_example.py @@ -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 - # 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 # ===========================