Merge pull request #103 from hadesto/dev/hadi/server-failover/feature

Server Failover Feature
This commit is contained in:
Peter Hamilton 2015-11-30 14:50:13 -05:00
commit 3afa0e8124
4 changed files with 107 additions and 17 deletions

View File

@ -18,4 +18,4 @@ formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

View File

@ -5,7 +5,7 @@ keyfile=None
certfile=None
cert_reqs=CERT_REQUIRED
ssl_version=PROTOCOL_SSLv23
ca_certs=../demos/certs/server.crt
ca_certs=./demos/certs/server.crt
do_handshake_on_connect=True
suppress_ragged_eofs=True
username=None
@ -15,8 +15,8 @@ timeout=30
[server]
host=127.0.0.1
port=5696
keyfile=../demos/certs/server.key
certfile=../demos/certs/server.crt
keyfile=./demos/certs/server.key
certfile=./demos/certs/server.crt
cert_reqs=CERT_NONE
ssl_version=PROTOCOL_SSLv23
ca_certs=None

View File

@ -76,7 +76,8 @@ CONFIG_FILE = os.path.normpath(os.path.join(FILE_PATH, '../kmipconfig.ini'))
class KMIPProxy(KMIP):
def __init__(self, host=None, port=None, keyfile=None, certfile=None,
def __init__(self, host=None, port=None, keyfile=None,
certfile=None,
cert_reqs=None, ssl_version=None, ca_certs=None,
do_handshake_on_connect=None,
suppress_ragged_eofs=None,
@ -193,7 +194,6 @@ class KMIPProxy(KMIP):
self.is_authentication_suite_supported(authentication_suite))
def open(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.logger.debug("KMIPProxy keyfile: {0}".format(self.keyfile))
self.logger.debug("KMIPProxy certfile: {0}".format(self.certfile))
@ -209,6 +209,23 @@ class KMIPProxy(KMIP):
self.logger.debug("KMIPProxy suppress_ragged_eofs: {0}".format(
self.suppress_ragged_eofs))
for host in self.host_list:
self.host = host
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._create_socket(sock)
self.protocol = KMIPProtocol(self.socket)
try:
self.socket.connect((self.host, self.port))
except Exception as e:
self.logger.error("An error occurred while connecting to "
"appliance " + self.host)
self.socket.close()
self.socket = None
else:
return
raise e
def _create_socket(self, sock):
self.socket = ssl.wrap_socket(
sock,
keyfile=self.keyfile,
@ -218,16 +235,8 @@ class KMIPProxy(KMIP):
ca_certs=self.ca_certs,
do_handshake_on_connect=self.do_handshake_on_connect,
suppress_ragged_eofs=self.suppress_ragged_eofs)
self.protocol = KMIPProtocol(self.socket)
self.socket.settimeout(self.timeout)
try:
self.socket.connect((self.host, self.port))
except socket.timeout as e:
self.logger.error("timeout occurred while connecting to appliance")
raise e
def __del__(self):
# Close the socket properly, helpful in case close() is not called.
self.close()
@ -881,9 +890,14 @@ class KMIPProxy(KMIP):
username, password, timeout):
conf = ConfigHelper()
self.host = conf.get_valid_value(
# TODO: set this to a host list
self.host_list_str = conf.get_valid_value(
host, self.config, 'host', conf.DEFAULT_HOST)
self.host_list = self._build_host_list(self.host_list_str)
self.host = self.host_list[0]
self.port = int(conf.get_valid_value(
port, self.config, 'port', conf.DEFAULT_PORT))
@ -922,11 +936,27 @@ class KMIPProxy(KMIP):
self.password = conf.get_valid_value(
password, self.config, 'password', conf.DEFAULT_PASSWORD)
self.timeout = conf.get_valid_value(
timeout, self.config, 'timeout', conf.DEFAULT_TIMEOUT)
self.timeout = int(conf.get_valid_value(
timeout, self.config, 'timeout', conf.DEFAULT_TIMEOUT))
if self.timeout < 0:
self.logger.warning(
"Negative timeout value specified, "
"resetting to safe default of {0} seconds".format(
conf.DEFAULT_TIMEOUT))
self.timeout = conf.DEFAULT_TIMEOUT
def _build_host_list(self, host_list_str):
'''
This internal function takes the host string from the config file
and turns it into a list
:return: LIST host list
'''
host_list = []
if isinstance(host_list_str, str):
host_list = host_list_str.replace(' ', '').split(',')
else:
raise TypeError("Unrecognized variable type provided for host "
"list string. 'String' type expected but '" +
str(type(host_list_str)) + "' received")
return host_list

View File

@ -61,6 +61,10 @@ from kmip.services.results import RekeyKeyPairResult
import kmip.core.utils as utils
import mock
import socket
class TestKMIPClient(TestCase):
@ -501,6 +505,62 @@ class TestKMIPClient(TestCase):
self.assertEqual(uid, result.uid)
self.assertEqual(names, result.names)
def test_host_list_import_string(self):
"""
This test verifies that the client can process a string with
multiple IP addresses specified in it. It also tests that
unnecessary spaces are ignored.
"""
host_list_string = '127.0.0.1,127.0.0.3, 127.0.0.5'
host_list_expected = ['127.0.0.1', '127.0.0.3', '127.0.0.5']
self.client._set_variables(host=host_list_string,
port=None, keyfile=None, certfile=None,
cert_reqs=None, ssl_version=None,
ca_certs=None,
do_handshake_on_connect=False,
suppress_ragged_eofs=None, username=None,
password=None, timeout=None)
self.assertEqual(host_list_expected, self.client.host_list)
def test_host_is_invalid_input(self):
"""
This test verifies that invalid values are not processed when
setting the client object parameters
"""
host = 1337
expected_error = TypeError
kwargs = {'host': host, 'port': None, 'keyfile': None,
'certfile': None, 'cert_reqs': None, 'ssl_version': None,
'ca_certs': None, 'do_handshake_on_connect': False,
'suppress_ragged_eofs': None, 'username': None,
'password': None, 'timeout': None}
self.assertRaises(expected_error, self.client._set_variables,
**kwargs)
@mock.patch('socket.socket.connect')
@mock.patch('ssl.SSLSocket.gettimeout')
def test_timeout_all_hosts(self, mock_ssl_timeout, mock_connect_return):
"""
This test verifies that the client will throw an exception if no
hosts are available for connection.
"""
mock_ssl_timeout.return_value = 1
mock_connect_return.return_value = socket.timeout
try:
self.client.open()
except Exception as e:
# TODO: once the exception is properly defined in the
# kmip_client.py file this test needs to change to reflect that.
self.assertIsInstance(e, Exception)
self.client.close()
else:
self.client.close()
class TestClientProfileInformation(TestCase):
"""