mirror of https://github.com/OpenKMIP/PyKMIP.git
Merge pull request #103 from hadesto/dev/hadi/server-failover/feature
Server Failover Feature
This commit is contained in:
commit
3afa0e8124
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue